home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / passwd+ / chfn.c next >
Encoding:
C/C++ Source or Header  |  1992-03-12  |  6.5 KB  |  356 lines

  1. #include "passwd.h"
  2.  
  3. #ifdef CHFN
  4.  
  5. /*
  6.  * change the gecos field
  7.  */
  8. chfn(p)
  9. struct passwd *p;        /* pointer to password structure */
  10. {
  11.     char buf[BUFSIZ];        /* buffer for new shell */
  12.     char prfmt[BUFSIZ];        /* printf format from field */
  13.     char list[BUFSIZ];        /* order to print things */
  14.     register char *s;        /* pointer to system shells */
  15.     char addr1[GECOSSIZE], addr2[GECOSSIZE], addr3[GECOSSIZE];
  16.     char addr4[GECOSSIZE], addr5[GECOSSIZE], addr6[GECOSSIZE];
  17.     char addr7[GECOSSIZE], addr8[GECOSSIZE], addr9[GECOSSIZE];
  18.     char *addrs[9];
  19.     FILE *fp;
  20.     register int i;
  21.     int doit;
  22.  
  23.     /*
  24.      * initialize the reading arrays
  25.      */
  26.     addrs[0] = addr1; addrs[1] = addr2; addrs[2] = addr3;
  27.     addrs[3] = addr4; addrs[4] = addr5; addrs[5] = addr6;
  28.     addrs[6] = addr7; addrs[7] = addr8; addrs[8] = addr9;
  29.  
  30.     /*
  31.      * print instructions
  32.      */
  33.     PRINTF("Changing finger information for %s.\n", p->pw_name);
  34.     PRINTF("Default values are printed inside of '[]'.\n");
  35.     PRINTF("To accept the default, type <return>.\n");
  36.     PRINTF("To have a blank entry, type the word 'none'.\n");
  37.  
  38.     /*
  39.      * open the test file
  40.      */
  41.     if ((fp = fopen(pwtest, "r")) == FI_NULL){
  42.         if (errno < sys_nerr){
  43.             LOG2(LG_SYSTEM, "%s: %s", pwtest, sys_errlist[errno]);
  44.         }
  45.         else{
  46.             LOG2(LG_SYSTEM, "%s: unknown error #%d",
  47.                             pwtest, errno);
  48.         }
  49.         perror("password format file");
  50.         exit(1);
  51.     }
  52.  
  53.     /*
  54.      * find and load the current information
  55.      */
  56.     doit = 0;
  57.     linect = 0;
  58.     while(fgets(buf, BUFSIZ, fp) != NULL){
  59.         /*
  60.          * kill the newline if any
  61.          */
  62.         if (*(s = &buf[strlen(buf)-1]) == '\n')
  63.             *s = '\0';
  64.             linect++;
  65.         /*
  66.          * look for the magic key words
  67.          */
  68.         if (strncmp(buf, "PROMPT:", 7) == 0){
  69.             getprompt(&buf[7]);
  70.             continue;
  71.         }
  72.         if (strncmp(buf, "GECOS:", 6) == 0){
  73.             (void) loadgecos(&buf[6], prfmt, list);
  74.             continue;
  75.         }
  76.         if (strncmp(buf, "SETGECOS:", 9) == 0){
  77.             /*
  78.              * now load the information
  79.              */
  80.             if (loadgecos(&buf[6], prfmt, list) >= 0){
  81.                 doit = 1;
  82.                 break;
  83.             }
  84.         }
  85.         /*
  86.          * force this format
  87.          */
  88.         if (strncmp(buf, "FORCEGECOS:", 11) == 0){
  89.             if (forcegecos(&buf[11], prfmt, list) >= 0)
  90.                 doit = 1;
  91.             break;
  92.         }
  93.     }
  94.  
  95.     /*
  96.      * be sure you can do something
  97.      */
  98.     if (doit == 0){
  99.         (void) strcmp(prfmt, "%s,%s,%s");
  100.         (void) strcpy(list, "not");
  101.     }
  102.  
  103.     /*
  104.      * have the user update it
  105.      */
  106.     for(i = 0; list[i] != '\0'; i++){
  107.         /*
  108.          * ask for update
  109.          */
  110.         prompt(list[i], buf);
  111.         /*
  112.          * read the response
  113.          */
  114.         if (fgets(addrs[i], BUFSIZ, stdin) == NULL){
  115.             PRINTF("Finger information unchanged.\n");
  116.             exit(0);
  117.         }
  118.         /*
  119.          * kill the newline if any
  120.          */
  121.         if (*(s = &addrs[i][strlen(addrs[i])-1]) == '\n')
  122.             *s = '\0';
  123.         /*
  124.          * if return, default stays
  125.          */
  126.         if (addrs[i][0] == '\0'){
  127.             (void) strcpy(addrs[i], buf);
  128.             continue;
  129.         }
  130.         /*
  131.          * if 'none', zap it
  132.          */
  133.         if (strcmp(buf, "none") == 0)
  134.             addrs[i][0] = '\0';
  135.         /*
  136.          * otherwise it's okay as it stands
  137.          */
  138.     }
  139.  
  140.     /*
  141.      * done -- update the record
  142.      */
  143.     fixup(prfmt);
  144.     SPRINTF(buf, prfmt, addr1, addr2, addr3, addr4, addr5, addr6,
  145.                             addr7, addr8, addr9);
  146.     p->pw_gecos = buf;
  147.     (void) update_pwd(p);
  148.  
  149.     /*
  150.      * bye
  151.      */
  152.     exit(0);
  153. }
  154.  
  155. /*
  156.  * change a prompt by user request
  157.  */
  158. getprompt(s)
  159. char *s;            /* line with request */
  160. {
  161.     char buf[BUFSIZ];        /* buffer for new prompt */
  162.     register char *b;        /* used to walk buffer */
  163.     register int i;            /* counter in a for loop */
  164.     char k;                /* key character */
  165.  
  166.     /*
  167.      * skip leading spaces to get to key character
  168.      */
  169.     while(isspace(*s))
  170.         s++;
  171.     if (!*s)
  172.         return;
  173.     /*
  174.      * grab key character
  175.      */
  176.     k = *s++;
  177.     /*
  178.      * eat spaces to go to prompt
  179.      */
  180.     while(isspace(*s))
  181.         s++;
  182.     /*
  183.      * at prompt; stuff it away
  184.      */
  185.     if (*s == '"'){
  186.         for (b = buf; *s && *s != '"'; *b++ = *s++);
  187.         if (!*s){
  188.             LOG1(LG_SYNTAX,
  189.                 "missing \" in PROMPT specification on line %d",
  190.                                 linect);
  191.             return;
  192.         }
  193.     }
  194.     else{
  195.         LOG1(LG_SYNTAX,
  196.             "missing \" in PROMPT specification on line %d", linect);
  197.         return;
  198.     }
  199.     /*
  200.      * update the prompt
  201.      */
  202.     for(i = 0; iv[i].name != '\0'; i++)
  203.         if (k == iv[i].name){
  204.             iv[i].prompt = strsave(buf);
  205.             return;
  206.         }
  207. }
  208.  
  209. /*
  210.  * prompt for update
  211.  */
  212. prompt(c, def)
  213. char c;            /* what to ask for */
  214. char def[];        /* default value */
  215. {
  216.     register struct intvar *ip;    /* points to internal variable */
  217.  
  218.     /*
  219.      * see if the prompt request can be met
  220.      */
  221.     ip = findiv(c);
  222.  
  223.     /*
  224.      * is not known, shrug;
  225.      * if known, prompt
  226.      */
  227.     def[0] = '\0';
  228.     if (ip->name == '\0')
  229.         PRINTF("Unknown field {best bet is to type 'none'} []: ");
  230.     else if (ip->string != CH_NULL){
  231.         PRINTF(ip->prompt, ip->string);
  232.         (void) strcpy(def, ip->string);
  233.     }
  234.     else
  235.         PRINTF(ip->prompt, "\0");
  236.     (void) fflush(stdout);
  237. }
  238.  
  239. /*
  240.  * this just says what should be in the GECOS field
  241.  */
  242. forcegecos(format, prfmt, list)
  243. char *format;            /* what to analyze */
  244. char *prfmt;            /* printf format string */
  245. char *list;            /* how to parse it */
  246. {
  247.     register char *f, *fb;    /* used to collect the format string */
  248.     register int i;        /* counter in a for loop */
  249.     register int n;        /* number of strings read in */
  250.  
  251.     /*
  252.      * now read in the format string
  253.      */
  254.     for(f = format; *f && *f != '"'; f++);
  255.     /*
  256.      * none present -- skip line
  257.      */
  258.     if (!*f)
  259.         return(-1);
  260.     /*
  261.      * skip initial quote, stuff string
  262.      */
  263.     n = 0;
  264.     fb = prfmt;
  265.     for(f++; *f && *f != '"'; *fb++ = *f++)
  266.         if (*f == '%'){
  267.             if (f[1] == '%')
  268.                 *fb++ = *f++;
  269.             else
  270.                 n++;
  271.         }
  272.     *fb = '\0';
  273.     /*
  274.      * no closing quote -- ignore line
  275.      */
  276.     if (!*f){
  277.         LOG1(LG_SYNTAX,
  278.             "missing \" in FORCEGECOS specification on line %d", linect);
  279.         return(-1);
  280.     }
  281.     /*
  282.      * skip closing quote
  283.      */
  284.     f++;
  285.     fb = f;
  286.     i = 0;
  287.     while(*fb && (findiv(*fb) != IV_NULL || isspace(*fb))){
  288.         if (!isspace(*fb))
  289.             list[i++] = *fb;
  290.         fb++;
  291.     }
  292.     if (*fb && findiv(*fb) == IV_NULL){
  293.         LOG2(LG_SYNTAX,
  294.             "bad FORCEGECOS specification at line %d (\"%s\")",
  295.                                 linect, fb);
  296.         return(-1);
  297.     }
  298.     else if (i != n){
  299.         LOG1(LG_SYNTAX,
  300.             "wrong number of escapes in FORCEGECOS specification on line %d",
  301.                 linect);
  302.         return(-1);
  303.     }
  304.  
  305.     return(0);
  306. }
  307.  
  308. /*
  309.  * this changes a scanf format into a printf format
  310.  */
  311. fixup(buf)
  312. char buf[];        /* format string */
  313. {
  314.     register char *b, *p;        /* used to copy string */
  315.  
  316.     /*
  317.      * ignore any %*<num><c>
  318.      * change any %[...] to %s
  319.      */
  320.     for(b = p = buf; *b; ){
  321.         if (*b != '%'){        /* not escape, copy */
  322.             *p++ = *b++;
  323.             continue;
  324.         }
  325.         if (*++b == '*'){    /* ignore this */
  326.             b++;
  327.             while(isdigit(*b))
  328.                 b++;
  329.             b++;
  330.             continue;
  331.         }
  332.         else if (*b == '['){    /* change this to %s */
  333.             while(*b && *b != ']')
  334.                 b++;
  335.             if (*b == ']')
  336.                 b++;
  337.             *p++ = '%';
  338.             *p++ = 's';
  339.             continue;
  340.         }
  341.         else{            /* copy this */
  342.             *p++ = '%';
  343.             while(isdigit(*b))
  344.                 *p++ = *b++;
  345.             *p++ = *b++;
  346.         }
  347.     }
  348.  
  349.     /*
  350.      * close off new string
  351.      */
  352.     *p++ = '\0';
  353. }
  354.  
  355. #endif
  356.